#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Common.Extensions/ObjectExtensions 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       对象扩展方法，提供各种对象类型的转换和操作功能
* 类 名：       ObjectExtensions
* 创建时间：  2025/5/22 10:00:31
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using JetBrains.Annotations;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    public static class ObjectExtensions
    {
    
        /// <summary>
        /// Used to simplify and beautify casting an object to a type.
        /// </summary>
        /// <typeparam name="T">Type to be casted</typeparam>
        /// <param name="obj">Object to cast</param>
        /// <returns>Casted object</returns>
        public static T As<T>(this object obj)
            where T : class
        {
            return (T)obj;
        }
        /// <summary>
        /// 判断对象是否在指定的数组中
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="item">要判断的对象</param>
        /// <param name="list">数组参数</param>
        /// <returns>如果在数组中返回true，否则返回false</returns>
        public static bool IsIn<T>(this T item, params T[] list)
        {
            return list.Contains(item);
        }
        /// <summary>
        /// 判断对象是否在指定的集合中
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="item">要判断的对象</param>
        /// <param name="items">集合对象</param>
        /// <returns>如果在集合中返回true，否则返回false</returns>
        public static bool IsIn<T>(this T item, IEnumerable<T> items)
        {
            return items.Contains(item);
        }
        /// <summary>
        /// 将对象转换为指定类型
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="this">源对象</param>
        /// <returns>转换后的对象</returns>
        public static T To<T>(this object @this)
        {
            if (@this == null)
            {
                return (T)(object)null;
            }

            var targetType = typeof(T);

            if (@this.GetType() == targetType)
            {
                return (T)@this;
            }
            var converter = TypeDescriptor.GetConverter(@this);
            if (converter != null)
            {
                if (converter.CanConvertTo(targetType))
                {
                    return (T)converter.ConvertTo(@this, targetType);
                }
            }

            converter = TypeDescriptor.GetConverter(targetType);
            if (converter != null)
            {
                if (converter.CanConvertFrom(@this.GetType()))
                {
                    return (T)converter.ConvertFrom(@this);
                }
            }

            if (@this == DBNull.Value)
            {
                return (T)(object)null;
            }

            return (T)Convert.ChangeType(@this, targetType);
        }
        /// <summary>
        /// 将对象转换为指定类型
        /// </summary>
        /// <param name="this">源对象</param>
        /// <param name="type">目标类型</param>
        /// <returns>转换后的对象</returns>
        public static object To([CanBeNull] this object @this, Type type)
        {
            if (@this != null)
            {
                var targetType = type;

                if (@this.GetType() == targetType)
                {
                    return @this;
                }

                var converter = TypeDescriptor.GetConverter(@this);
                if (converter != null)
                {
                    if (converter.CanConvertTo(targetType))
                    {
                        return converter.ConvertTo(@this, targetType);
                    }
                }

                converter = TypeDescriptor.GetConverter(targetType);
                if (converter != null)
                {
                    if (converter.CanConvertFrom(@this.GetType()))
                    {
                        return converter.ConvertFrom(@this);
                    }
                }

                if (@this == DBNull.Value)
                {
                    return null;
                }

                return Convert.ChangeType(@this, targetType);
            }

            return @this;
        }
        /// <summary>
        /// 将对象转换为DateTime类型
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <returns>转换后的DateTime对象，转换失败返回DateTime.MinValue</returns>
        public static DateTime ToDateTime(this object thisValue)
        {
            DateTime reval = DateTime.MinValue;
            if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
            {
                reval = Convert.ToDateTime(thisValue);
            }
            return reval;
        }

        /// <summary>
        /// 将object转换为DateTime类型信息。
        /// </summary>
        /// <param name="o">object。</param>
        /// <param name="t">默认值。</param>
        /// <returns>DateTime。</returns>
        public static DateTime ToDateTime(this object o, DateTime t = default(DateTime))
        {
            if (t == default(DateTime))
            {
                t = new DateTime(1753, 1, 1);
            }
            DateTime info;
            if (!DateTime.TryParse(o.ToString(), out info))
            {
                info = t;
            }
            return info;
        }
        /// <summary>
        /// 将对象转换为long类型
        /// </summary>
        /// <param name="s">源对象</param>
        /// <returns>转换后的long值，转换失败返回0</returns>
        public static long ToLong(this object s)
        {
            if (s == null || s == DBNull.Value)
                return 0L;

            long.TryParse(s.ToString(), out long result);
            return result;
        }

        /// <summary>
        /// 将对象转换为double类型的金额
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <returns>转换后的double值，转换失败返回0</returns>
        public static double ToMoney(this object thisValue)
        {
            double reval;
            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return 0;
        }
        /// <summary>
        /// 将对象转换为double类型的金额
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <param name="errorValue">转换失败时返回的默认值</param>
        /// <returns>转换后的double值，转换失败返回指定的默认值</returns>
        public static double ToMoney(this object thisValue, double errorValue)
        {
            double reval;
            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }

        /// <summary>
        /// 将对象转换为字符串
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <returns>转换后的字符串，如果为null则返回空字符串</returns>
        public static string ToString(this object thisValue)
        {
            if (thisValue != null) return thisValue.ToString().Trim();
            return "";
        }
        /// <summary>
        /// 将对象转换为字符串
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <param name="errorValue">转换失败时返回的默认值</param>
        /// <returns>转换后的字符串，如果为null则返回指定的默认值</returns>
        public static string ToString(this object thisValue, string errorValue)
        {
            if (thisValue != null) return thisValue.ToString().Trim();
            return errorValue;
        }

        /// <summary>
        /// 将对象转换为float类型
        /// </summary>
        /// <param name="s">源对象</param>
        /// <param name="digits">小数位数，如果为null则不进行舍入</param>
        /// <returns>转换后的float值，转换失败返回0</returns>
        public static float ToFloat(this object s, int? digits = null)
        {
            if (s == null || s == DBNull.Value)
                return 0f;

            float.TryParse(s.ToString(), out float result);

            if (digits == null)
                return result;

            return (float)Math.Round(result, digits.Value);
        }

        /// <summary>
        /// 将对象转换为double类型
        /// </summary>
        /// <param name="s">源对象</param>
        /// <param name="digits">小数位数，如果为null则不进行舍入</param>
        /// <returns>转换后的double值，转换失败返回0</returns>
        public static double ToDouble(this object s, int? digits = null)
        {
            if (s == null || s == DBNull.Value)
                return 0d;

            double.TryParse(s.ToString(), out double result);

            if (digits == null)
                return result;

            return Math.Round(result, digits.Value);
        }

        /// <summary>
        /// 将对象转换为decimal类型
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <returns>转换后的decimal值，转换失败返回0</returns>
        public static decimal ObjToDecimal(this object thisValue)
        {
            decimal reval;
            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return 0;
        }

        /// <summary>
        /// 将对象转换为decimal类型
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <param name="errorValue">转换失败时返回的默认值</param>
        /// <returns>转换后的decimal值，转换失败返回指定的默认值</returns>
        public static decimal ObjToDecimal(this object thisValue, decimal errorValue)
        {
            decimal reval;
            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }
        /// <summary>
        /// 将对象转换为bool类型
        /// </summary>
        /// <param name="thisValue">源对象</param>
        /// <returns>转换后的bool值，转换失败返回false</returns>
        public static bool ToBool(this object thisValue)
        {
            bool reval = false;
            if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return reval;
        }

        /// <summary>
        /// 将对象转换为byte类型
        /// </summary>
        /// <param name="s">源对象</param>
        /// <returns>转换后的byte值，转换失败返回0</returns>
        public static byte ToByte(this object s)
        {
            if (s == null || s == DBNull.Value)
                return 0;

            byte.TryParse(s.ToString(), out byte result);
            return result;
        }
        /// <summary>
        /// 转换为16进制
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="lowerCase">是否小写</param>
        /// <returns></returns>
        public static string ToHex(this byte[] bytes, bool lowerCase = true)
        {
            if (bytes == null)
                return null;

            var result = new StringBuilder();
            var format = lowerCase ? "x2" : "X2";
            for (var i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString(format));
            }

            return result.ToString();
        }

        /// <summary>
        /// 16进制转字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexToBytes(this string s)
        {
            if (s.IsNull())
                return null;
            var bytes = new byte[s.Length / 2];

            for (int x = 0; x < s.Length / 2; x++)
            {
                int i = (Convert.ToInt32(s.Substring(x * 2, 2), 16));
                bytes[x] = (byte)i;
            }

            return bytes;
        }

        /// <summary>
        /// 转换为Base64
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToBase64(this byte[] bytes)
        {
            if (bytes == null)
                return null;

            return Convert.ToBase64String(bytes);
        }
        /// <summary>
        /// 将对象转换为int类型
        /// </summary>
        /// <param name="s">源对象</param>
        /// <param name="round">是否四舍五入</param>
        /// <returns>转换后的int值，转换失败返回0</returns>
        public static int ToInt(this object s, bool round = false)
        {
            if (s == null || s == DBNull.Value)
                return 0;

            if (s is bool b)
                return b ? 1 : 0;

            if (int.TryParse(s.ToString(), out int result))
                return result;

            if (s.GetType().IsEnum)
            {
                return (int)s;
            }

            var f = s.ToFloat();
            return round ? Convert.ToInt32(f) : (int)f;
        }


        /// <summary>
        /// 将毫秒时间戳转换为DateTime
        /// </summary>
        /// <param name="milliseconds">毫秒时间戳</param>
        /// <returns>转换后的DateTime对象</returns>
        public static DateTime ToDateTime(this long milliseconds)
        {
            return DateTimeExtensions.TimestampStart.AddMilliseconds(milliseconds);
        }
        public static T ToOrDefault<T>([CanBeNull] this object @this, Func<object, T> defaultValueFactory)
        {
            try
            {
                return (T)@this.To(typeof(T));
            }
            catch (Exception)
            {
                return defaultValueFactory(@this);
            }
        }
        public static T ToOrDefault<T>([NotNull] this object @this, Func<T> defaultValueFactory)
        {
            return @this.ToOrDefault(x => defaultValueFactory());
        }
        public static object ToOrDefault([NotNull] this object @this, [NotNull] Type type)
        {
            try
            {
                return @this.To(type);
            }
            catch (Exception)
            {
                return type.GetDefaultValue();
            }
        }
        public static T ToOrDefault<T>([CanBeNull] this object @this)
        {
            return @this.ToOrDefault(x => default(T));
        }
        public static T ToOrDefault<T>([CanBeNull] this object @this, T defaultValue)
        {
            return @this.ToOrDefault(x => defaultValue);
        }
    /// <summary>
        /// 判断对象是否为null或DBNull
        /// </summary>
        /// <param name="obj">要判断的对象</param>
        /// <returns>如果是null或DBNull返回true，否则返回false</returns>
        public static bool IsNull(this object obj)
        {
            return obj == null || obj == DBNull.Value;
        }

        /// <summary>
        /// 判断对象是否不为null且不为DBNull
        /// </summary>
        /// <param name="obj">要判断的对象</param>
        /// <returns>如果不是null且不是DBNull返回true，否则返回false</returns>
        public static bool IsNotNull(this object obj)
        {
            return !obj.IsNull();
        }

        /// <summary>
        /// 安全获取对象的字符串表示
        /// </summary>
        /// <param name="obj">源对象</param>
        /// <returns>对象的字符串表示，如果为null则返回空字符串</returns>
        public static string SafeToString(this object obj)
        {
            return obj?.ToString() ?? string.Empty;
        }

        /// <summary>
        /// 判断对象是否为默认值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="value">要判断的对象</param>
        /// <returns>如果是默认值返回true，否则返回false</returns>
        public static bool IsDefault<T>(this T value)
        {
            return EqualityComparer<T>.Default.Equals(value, default);
        }

    }
}
